#include "TowerManager.h"
#include "ConfigManager.h"
#include "ArcherTower.h"
#include "AxemanTower.h"
#include "GunnerTower.h"

void TowerManager::OnUpdate(double delta)
{
    for (Tower *tower: towerList)
        tower->OnUpdate(delta);
}

void TowerManager::OnRender(SDL_Renderer *renderer)
{
    for (Tower *tower: towerList)
        tower->OnRender(renderer);
}

double TowerManager::GetPlaceCost(TowerType type)
{
    static ConfigManager &instance = ConfigManager::Instance();

    switch (type) {
        case Archer:
            return instance.archer_template.cost[instance.level_archer];
            break;
        case Axeman:
            return instance.axeman_template.cost[instance.level_axeman];
            break;
        case Gunner:
            return instance.gunner_template.cost[instance.level_gunner];
            break;
    }

    return 0;
}

double TowerManager::GetUpgradeCost(TowerType type)
{
    static ConfigManager &instance = ConfigManager::Instance();

    switch (type) {
        case Archer:
            return instance.level_archer == 9 ? -1 :
                   instance.archer_template.upgrade_cost[instance.level_archer];
            break;
        case Axeman:
            return instance.level_axeman == 9 ? -1 :
                   instance.axeman_template.upgrade_cost[instance.level_axeman];
            break;
        case Gunner:
            return instance.level_gunner == 9 ? -1 :
                   instance.gunner_template.upgrade_cost[instance.level_gunner];
            break;
    }

    return 0;
}

double TowerManager::GetDamageRange(TowerType type)
{
    static ConfigManager &instance = ConfigManager::Instance();

    switch (type) {
        case Archer:
            return instance.archer_template.view_range[instance.level_archer];
            break;
        case Axeman:
            return instance.axeman_template.view_range[instance.level_axeman];
            break;
        case Gunner:
            return instance.gunner_template.view_range[instance.level_gunner];
            break;
    }

    return 0;
}

void TowerManager::PlaceTower(TowerType type, const SDL_Point &idx)
{
    Tower *tower = nullptr;

    switch (type) {
        case Archer:
            tower = new ArcherTower();
            break;
        case Axeman:
            tower = new AxemanTower();
            break;
        case Gunner:
            tower = new GunnerTower();
            break;
        default:
            tower = new ArcherTower();
            break;
    }

    static Vector2 position;
    static const SDL_Rect &rect = ConfigManager::Instance().rectTileMap;

    position.x = rect.x + idx.x * SIZE_TILE + SIZE_TILE / 2;
    position.y = rect.y + idx.y * SIZE_TILE + SIZE_TILE / 2;
    tower->SetPosition(position);
    towerList.push_back(tower);

    ConfigManager::Instance().map.PlaceTower(idx);
    static const ResourcesManager::SoundPool &sound_pool = ResourcesManager::Instance().soundPool;
    Mix_PlayChannel(-1, sound_pool.find(ResID::Sound_PlaceTower)->second, 0);
}

void TowerManager::UpgradeTower(TowerType type)
{
    static ConfigManager &instance = ConfigManager::Instance();

    switch (type) {
        case Archer:
            instance.level_archer = instance.level_archer >= 9 ? 9 : instance.level_archer + 1;
            break;
        case Axeman:
            instance.level_axeman = instance.level_axeman >= 9 ? 9 : instance.level_axeman + 1;
            break;
        case Gunner:
            instance.level_gunner = instance.level_gunner >= 9 ? 9 : instance.level_gunner + 1;
            break;
    }
    static const ResourcesManager::SoundPool &sound_pool = ResourcesManager::Instance().soundPool;
    Mix_PlayChannel(-1, sound_pool.find(ResID::Sound_TowerLevelUp)->second, 0);
}